
#ifndef _LOGGING_LOG_H_
#define _LOGGING_LOG_H_

#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <compile.h>

#ifndef NDEBUG
	void Log_Buf(uint8_t ch, const char* color, const uint8_t* buf, uint32_t len, uint8_t align, const char* tag, ...);
	int Log_Log(uint8_t ch, const char* color, const char* tag, const char* sFormat, ...);
	void Log_Head(uint8_t ch, const char* color, const char* tag);
    #if defined(ENABLE_SEMIHOST)
    #define DBG_CH_WRITE(ch, str)        printf("%s", str)
    #define DBG_CH_PRINT(ch, ...)       printf(fmt, __VA_ARGS__)
    #else
    #include "./SystemView/SEGGER_RTT.h"
	#define DBG_CH_PRINT(ch, ...)	SEGGER_RTT_printf(ch, __VA_ARGS__)	
	#define DBG_CH_WRITE(ch, str)	SEGGER_RTT_WriteString(ch, str)
	#define DBG_CH_PUT_CHAR(ch, c)	SEGGER_RTT_PutCharSkip(ch, c)
    #endif
	#define DBG_CH_HEAD(ch, color, tag)		Log_Head(ch, color, tag)
	#define DBG_CH_PRINT_BUF(ch, buf, len)	\
		do{ unsigned int i; 	\
			const unsigned char *_buf = (const unsigned char*)(buf); unsigned int _len = (len);	\
			for(i = 0; i < _len; ++i)	DBG_CH_PRINT(ch, "%02X ", _buf[i]); \
		}while(0)
#else
#define DBG_CH_WRITE(ch, str)
#define DBG_CH_PRINT(ch, ...)
#define DBG_CH_PRINT_BUF(ch, buf, len)
#define DBG_CH_PUT_CHAR(ch, c)
#define DBG_CH_HEAD(ch, color, tag)
#endif


#define DBG_PRINT(...)		DBG_CH_PRINT(0,  __VA_ARGS__)
#define DBG_WRITE(str)		DBG_CH_WRITE(0, str)
#define DBG_PRINT_BUF(buf, len)	DBG_CH_PRINT_BUF(0, buf, len)
#define DBG_PUT_CHAR(c)		DBG_CH_PUT_CHAR(0, c)

#define MDBG_PRINT(m, ...)			if(m) DBG_PRINT( __VA_ARGS__)
#define MDBG_PRINT_BUF(m, buf, len)		if(m) DBG_PRINT_BUF(buf, len)
#define MDBG_WRITE(m, str)			if(m) DBG_WRITE(str)

#define MDBG_CH_PRINT(m, ch, ...)	if(m) DBG_CH_PRINT(ch, __VA_ARGS__)
#define MDBG_CH_PRINT_BUF(m, ch, buf, len)	if(m) DBG_CH_PRINT_BUF(ch, buf, len)
#define MDBG_CH_WRITE(m, ch, str)		if(m) DBG_CH_WRITE(ch, str)

//#define DBG_FUNC()	LOGD("", "%s", __func__)

//添加时间戳

#define LOG_TIME_ENABLE	1

#if LOG_TIME_ENABLE

#ifndef LOG_TIME_ON
#define LOG_TIME_ON		1
#endif
unsigned int Log_Time(void);

#define LOG_TIME()	if(LOG_TIME_ON){DBG_PRINT("[%010u]", Log_Time());}

#else

#define LOG_TIME()

#endif
//日志登记
#define LOG_VERBOSE		5
#define LOG_DEBUG		4
#define LOG_INFO		3
#define LOG_WARN		2
#define LOG_ERROR		1
#define LOG_OFF			0

#ifndef LOG_LEVE
#define LOG_LEVE		LOG_VERBOSE
#endif

//通道选择
#ifndef NDEBUG
#define LOG_To(id)		SEGGER_RTT_SetTerminal(id)
#else
#define LOG_To(id)		
#endif

//全局日志
//#define LOG(ch, color, tag, ...)		do{LOG_To(ch); DBG_WRITE(color); LOG_TIME(); DBG_WRITE(tag);DBG_WRITE(": "); DBG_PRINT( __VA_ARGS__);}while(0)
#define LOGX(ch, color, tag, ...)		do{DBG_CH_HEAD(ch, color, tag); DBG_PRINT( __VA_ARGS__);}while(0)
//#define LOG(ch, color, tag, ...)		Log_Log(ch, color, tag, const char * sFormat, ...)

#define LOGV(tag, ...)	do{if(LOG_VERBOSE <= LOG_LEVE){LOGX(1, RTT_CTRL_TEXT_BRIGHT_CYAN, tag, __VA_ARGS__); DBG_WRITE("\r\n");}}while(0)
#define LOGD(tag, ...)	do{if(LOG_DEBUG <= LOG_LEVE){LOGX(0, RTT_CTRL_TEXT_BRIGHT_WHITE, tag, __VA_ARGS__); DBG_WRITE("\r\n");}}while(0)
#define LOGI(tag, ...)	do{if(LOG_INFO <= LOG_LEVE){LOGX(0, RTT_CTRL_TEXT_BRIGHT_GREEN, tag, __VA_ARGS__); DBG_WRITE("\r\n");}}while(0)
#define LOGW(tag, ...)	do{if(LOG_WARN <= LOG_LEVE){LOGX(0, RTT_CTRL_TEXT_BRIGHT_YELLOW, tag, __VA_ARGS__); DBG_WRITE("\r\n");}}while(0)
#define LOGE(tag, ...)	do{if(LOG_ERROR <= LOG_LEVE){LOGX(0, RTT_CTRL_TEXT_BRIGHT_RED, tag, __VA_ARGS__); DBG_WRITE("\r\n");}}while(0)

//	#define LOG_BUF(ch, color, tag, buf, len)	do{LOG_To(ch); DBG_WRITE(color); LOG_TIME(); DBG_WRITE(tag);DBG_WRITE(": "); DBG_PRINT_BUF(buf, len); DBG_WRITE("\r\n");}while(0)
#ifndef NDEBUG
#define LOG_BUF(ch, color, tag, buf, len)	Log_Buf(ch, color, buf, len, 16, tag)
#define LOG_BUFS(tag, buf, len)		Log_Buf(0, RTT_CTRL_TEXT_BRIGHT_WHITE, buf, len, 16, tag)
#define LOG_SBUF(tag, buf, len)		LOG_BUFS(tag, buf, len)
#else
#define LOG_BUF(ch, color, tag, buf, len)	
#define LOG_BUFS(tag, buf, len)
#define LOG_SBUF(tag, buf, len)
#endif

#define LOG_EM(...)    LOGE("", __VA_ARGS__)
#define LOG_ALERT(...) LOGE("", __VA_ARGS__)
#define LOG_CRIT(...)  LOGE("", __VA_ARGS__)
#define LOG_ERR(...)   LOGE("", __VA_ARGS__)
#define LOG_INF(...)   LOGI("", __VA_ARGS__)
#define LOG_WRN(...)   LOGW("", __VA_ARGS__)
#define LOG_NOT(...)   LOGV("", __VA_ARGS__)
#define LOG_DBG(...)   LOGD("", __VA_ARGS__)

//#define LOG_E		LOGE

//本地日志
#ifndef LOCAL_LOG
	#define LOCAL_LOG	0
#endif

#define LLOGV(tag, ...)	do{if(LOCAL_LOG){LOGV(tag, __VA_ARGS__);}}while(0)
#define LLOGD(tag, ...)	do{if(LOCAL_LOG){LOGD(tag, __VA_ARGS__);}}while(0)
#define LLOGI(tag, ...)	do{if(LOCAL_LOG){LOGI(tag, __VA_ARGS__);}}while(0)
#define LLOGW(tag, ...)	do{if(LOCAL_LOG){LOGW(tag, __VA_ARGS__);}}while(0)
#define LLOGE(tag, ...)	do{if(LOCAL_LOG){LOGE(tag, __VA_ARGS__);}}while(0)

#define LLOG_BUF(ch, color, tag, buf, len)	do{if(LOCAL_LOG){LOG_BUF(ch, color, tag, buf, len);}}while(0)
#define LLOG_BUFS(tag, buf, len)	do{if(LOCAL_LOG){LOG_BUF(0, RTT_CTRL_TEXT_BRIGHT_WHITE, tag, buf, len);}}while(0)
//全局记录
#define TRACE_V(...)	LOGV(__func__, __VA_ARGS__)
#define TRACE_D(...)	LOGD(__func__, __VA_ARGS__)
#define TRACE_I(...)	LOGI(__func__, __VA_ARGS__)
#define TRACE_W(...)	LOGW(__func__, __VA_ARGS__)
#define TRACE_E(...)	LOGE(__func__, __VA_ARGS__)
#define TRACE_BUF(ch, color, buf, len)	LOG_BUF(ch, color, __func__, buf, len)
#define TRACE_BUFS(buf, len)	do{if(LOCAL_TRACE)TRACE_BUF(0, RTT_CTRL_TEXT_BRIGHT_WHITE, buf, len);}while(0)
//本地记录
#ifndef LOCAL_TRACE
	#define LOCAL_TRACE	0
#endif

#define LTRACE_V(...)	do{if(LOCAL_TRACE)TRACE_V(__VA_ARGS__);}while(0)
#define LTRACE_D(...)	do{if(LOCAL_TRACE)TRACE_D(__VA_ARGS__);}while(0)
#define LTRACE_I(...)	do{if(LOCAL_TRACE)TRACE_I(__VA_ARGS__);}while(0)
#define LTRACE_W(...)	do{if(LOCAL_TRACE)TRACE_W(__VA_ARGS__);}while(0)
#define LTRACE_E(...)	do{if(LOCAL_TRACE)TRACE_E(__VA_ARGS__);}while(0)
#define LTRACE_BUF(ch, color, buf, len)	do{if(LOCAL_TRACE)TRACE_BUF(ch, color, buf, len);}while(0)
#define LTRACE_BUFS(buf, len)	do{if(LOCAL_TRACE)TRACE_BUF(0, RTT_CTRL_TEXT_BRIGHT_WHITE, buf, len);}while(0)

#endif //_LOGGING_LOG_H_




